package com.timk.goserver.server.services;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.hibernate.Session;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.timk.goserver.client.services.NoSessionException;
import com.timk.goserver.server.model.LoginCookie;
import com.timk.goserver.server.util.HibernateUtil;

/**
 * Base class for service servlets
 * @author TKington
 *
 */
public class AbstractServiceServlet extends RemoteServiceServlet {
	/** Version of server.  Bumping this forces users to log in again. */
	public static final int VERSION = 15;
	
	protected HttpSession getSession() throws NoSessionException {
		HttpSession session = getThreadLocalRequest().getSession();
		if(session == null) {
			throw new NoSessionException("Your session has expired. Please log in.");
		}
		
		String verStr = (String)session.getAttribute("version");
		if(verStr == null && !loadSessionFromDB()) {
			throw new NoSessionException("Your session has expired. Please log in.");
		}
		
		verStr = (String)session.getAttribute("version");
		int version = Integer.parseInt(verStr);
		if(version != VERSION) {
			throw new NoSessionException(
					"The server has been updated.  Please log in again.");
		}
		
		return session;
	}
	
	private boolean loadSessionFromDB() {
		HttpServletRequest request = getThreadLocalRequest();
		Cookie cookie = getLoginCookie(request);
		if(cookie == null) {
			return false;
		}
		
		long cookieNum = Long.parseLong(cookie.getValue());
		
		Session hbSession = HibernateUtil.startTrans();
		LoginCookie loginCookie = (LoginCookie)hbSession
				.createQuery("from LoginCookie as c where c.cookieNum = ?")
				.setLong(0, cookieNum)
				.uniqueResult();
		
		hbSession.getTransaction().commit();
		
		HttpSession session = request.getSession();
		session.setAttribute("version",
				String.valueOf(loginCookie.getSessionVersion()));
		session.setAttribute("username", loginCookie.getUsername());
		
		return true;
	}

	/**
	 * Finds the persistent login cookie for this client.
	 * 
	 * @param request the servlet request
	 * @return the cookie, or null
	 */
	public static Cookie getLoginCookie(HttpServletRequest request) {
		Cookie [] cookies = request.getCookies();
		if(cookies == null) {
			return null;
		}
		
		Cookie cookie = null;
		for(int i = 0; i < cookies.length; i++) {
			if("persistLogin".equals(cookies[i].getName())) {
				cookie = cookies[i];
				break;
			}
		}
		
		return cookie;
	}
	
	protected String getCurrentUsername() throws NoSessionException {
		return (String)getSession().getAttribute("username");
	}
}
